package ssm.ann;

import org.h2.server.web.DbStarter;
import org.h2.server.web.WebServlet;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import ssm.ann.config.RootConfig;
import ssm.ann.config.ServletConfig;

import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletContext;
import javax.servlet.ServletRegistration;

public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected Class<?>[] getRootConfigClasses() { // spring 配置
        return new Class<?>[]{RootConfig.class};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() { // spring mvc 配置
        return new Class<?>[]{ServletConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        // https://blog.csdn.net/f641385712/article/details/118276037

        // / 是 servlet 中特殊的匹配模式，用在 Filter 中无效
        // 是缺省匹配代表匹配所有路径，所以只可能存在一个实例，若存在多个就覆盖
        // 优先级最低（兜底），这是和 /* 的最大区别。它不会覆盖任何其它的 url-pattern，只会覆盖 Servlet 容器（如 Tomcat）内建的 DefaultServlet
        // DispatcherServlet 不会拦截 .jsp 结尾的请求。是因为 Servlet 容器（如 Tomcat）内置有专门匹配 .jsp 这种请求的 Servlet 处理器：JspServlet

        // /* 属于 4 中匹配模式中的路径匹配，可用于 Servlet 和 Filter
        // 优先级很高（仅次于精确匹配）。所以它会覆盖所有的后缀名匹配，从而很容易引起 404 问题，所以这种模式的“伤害性”是非常强的，一般有且仅用在 Filter 上

        // 当一个 url 与多个 servlet 的匹配规则可以匹配时，则按照：“精确路径 > 最长路径 > 扩展名” 这样的优先级匹配到对应的 servlet。
        // 所以一般来说我们的 DispatcherServlet 一般都是最后被匹配上的（若有多个 Servlet 匹配的情况下）
        return new String[]{"/"};
    }

    /**
     * 文件上传设置
     * https://www.cnblogs.com/yy3b2007com/p/11783661.html
     * https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-multipart
     * https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/multipart/support/StandardServletMultipartResolver.html
     *
     * @see org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration
     */
    @Override
    protected void customizeRegistration(ServletRegistration.Dynamic registration) {
        // Optionally also set maxFileSize, maxRequestSize, fileSizeThreshold
        registration.setMultipartConfig(new MultipartConfigElement("/tmp"));
    }

    /**
     * * @Autowired
     * * private ServletContext servletContext;
     * 在 Spring 的 config 里，不允许通过 servletContext 再向 web 容器添加 servlet
     */
    @Override
    protected void registerDispatcherServlet(ServletContext servletContext) { // 注册 servlet
        super.registerDispatcherServlet(servletContext);
        // servletContext.addServlet("BeanName", new HelloServlet()).addMapping("/helloService");
        servletContext.addServlet("h2", new WebServlet()).addMapping("/h2/*");
    }

    @Override
    protected void registerContextLoaderListener(ServletContext servletContext) { // 注册 listener
        super.registerContextLoaderListener(servletContext);
        servletContext.addListener(new DbStarter());
    }
}
